import G6 from '@antv/g6';
import { NODE, ANCHORS } from '../utils/constants';
import { randomKey } from 'src/utils/utils';
/**
 * @Method drag-add-node
 * 拖拽添加节点的交互
 */

// 封装点击添加边的交互
G6.registerBehavior('drag-add-node', {
  // 设定该自定义行为需要监听的事件及其响应函数
  getEvents() {
    return {
      'canvas:click': 'onCanvasClick',
      'node:mousedown': 'onNodeMouseDown',
      'node:mouseup': 'onNodeMouseUp',
      // 'node:click': 'onNodeClick', // 监听事件 node:click，响应函数时 onClick
      mousemove: 'onMousemove', // 监听事件 mousemove，响应函数时 onMousemove
      mouseup: 'onMouseup', // 画布上的mouseup
      'edge:click': 'onEdgeClick', // 监听事件 edge:click，响应函数时 onEdgeClick
    };
  },
  onCanvasClick(ev) {
    if (this.edge) {
      this.currentEdge = null;
    }
  },

  onNodeMouseDown(ev) {
    this.sourceNode = ev.item;
    const graph = this.graph;
    // 鼠标当前点击的节点的位置
    const point = { x: ev.x, y: ev.y };
    const model = this.sourceNode.getModel();
    // 并不是在连线中,即mousedown的开始节点
    if (!(this.addingEdge && this.edge)) {
      // 如果点击的不是node上的锚点（因为锚点是circle组成），则返回
      if (ev.target._cfg && ev.target._cfg.type !== 'circle') {
        return;
      }
      //如果点击的是下锚点，则将节点锁定，禁止拖拽
      this.sourceNode.lock();
      console.log(ev.target);
      // 如果点击的是下锚点
      if (ev.target._attrs.position === ANCHORS[1]._POSITION) {
        // 判断下source 节点的类型，如果是分流节点，则设置label的值
        let label = '';
        if (model.id) {
          const source = graph.findById(model.id);
          const { type } = source.getModel();
          // 如果是分流节点，则需要加入label+分流比例
          if (type === NODE._CROSS) {
            const outEdeges = source.getOutEdges();
            const outEdegesIndex = outEdeges.length;
            label = `c${outEdegesIndex}`;
            const totalPercent = outEdeges.reduce((total, it) => {
              total += it.getModel().percent || 0;
              return total;
            }, 0);
            // 在图上新增一条边，结束点是鼠标当前点击的节点的位置
            this.edge = graph.addItem('edge', {
              id: randomKey(),
              source: model.id,
              target: point,
              shape: 'line-arrow',
              label: label,
              percent: 100 - totalPercent >= 0 ? 100 - totalPercent : 0,
            });
          } else {
            // 在图上新增一条边，结束点是鼠标当前点击的节点的位置
            this.edge = graph.addItem('edge', {
              id: randomKey(),
              source: model.id,
              target: point,
              shape: 'line-arrow',
              sourceAnchor: 1,
              targetAnchor: 0,
            });
          }
        }

        this.addingEdge = true;
      }
      // 如果source节点是结束节点，则返回
      if (model.shape === NODE._END) {
        this.graph.removeItem(this.edge);
        return;
      }
    }
  },
  // 在node节点上mouseup
  onNodeMouseUp(ev) {
    this.sourceNode = null;
  },

  // getEvents 中定义的 mousemove 的响应函数
  onMousemove(ev) {
    // 鼠标的当前位置
    const point = { x: ev.x, y: ev.y };
    if (this.addingEdge && this.edge) {
      // 更新边的结束点位置为当前鼠标位置
      this.graph.updateItem(this.edge, {
        target: point,
      });
    }
  },

  //  mouseup 的响应函数,如果正在连线，则移除线
  onMouseup(ev) {
    const node = ev.item;
    const graph = this.graph;
    this.sourceNode && this.sourceNode.unlock();
    if (!node) {
      this.graph.removeItem(this.edge);
      this.addingEdge = false;
      return;
    }
    const model = node.getModel();
    // 如果mouseup的时候是在画布中的线上，则移除线
    if (model.shape === 'line-arrow') {
      this.graph.removeItem(this.edge);
      this.addingEdge = false;
      return;
    }

    // 并不是在连线中,即点击的开始节点
    if (this.addingEdge && this.edge) {
      if (this.edge.getModel()) {
        // 如果target节点是开始节点，则返回
        if (model.shape === NODE._START) {
          this.graph.removeItem(this.edge);
          this.addingEdge = false;
          return;
        }
        // 连接节点起止都是同一个节点，则返回
        if (model.id === this.edge.getModel().source) {
          this.graph.removeItem(this.edge);
          this.addingEdge = false;
          return;
        }
        const nodes = this.graph.getNodes();
        const source = nodes.find((it) => it._cfg.id === this.edge.getModel().source);
        // 连接source节点是开始，target节点是结束节点，则返回
        if (source._cfg.currentShape === 'start' && model.type === 'end') {
          this.graph.removeItem(this.edge);
          this.addingEdge = false;
          return;
        }
        // 查询线edegs里面是否已存在(target相同，source也相同|| 反过来联线)，如果存在，则返回
        if (
          this.graph.getEdges().find((it) => {
            const source = it.getModel().source;
            const target = it.getModel().target;
            return (
              (source === this.edge.getModel().source && target === model.id) ||
              (target === this.edge.getModel().source && source === model.id)
            );
          })
        ) {
          this.graph.removeItem(this.edge);
          this.addingEdge = false;
          return;
        }
        console.log(this.edge);
        // const {source} = this.edge.getModel();
        graph.updateItem(this.edge, {
          target: model.id,
        });

        this.edge = null;
        this.addingEdge = false;
      }
    }
  },
  // 线的onEdgeMouseEnter
  onEdgeMouseEnter(ev) {
    if (!this.addingEdge || !this.edge) {
      const currentEdge = ev.item;
      this.graph.setItemState(currentEdge, 'active', true);
    }
  },
  onEdgeMouseLeave(ev) {
    if (!this.addingEdge || !this.edge) {
      const currentEdge = ev.item;
      this.graph.setItemState(currentEdge, 'active', currentEdge.hasState('selected'));
    }
  },
  // getEvents 中定义的 'edge:click' 的响应函数
  onEdgeClick(ev) {
    const currentEdge = ev.item;
    // 拖拽过程中，点击会点击到新增的边上
    if (this.addingEdge && this.edge === currentEdge) {
      this.graph.removeItem(this.edge);
      this.edge = null;
      this.addingEdge = false;
      // 非拖拽过程，则点击到的当前线
    } else {
      this.currentEdge = currentEdge;
      this.graph.setItemState(this.currentEdge, 'active', false);
      this.graph.setItemState(this.currentEdge, 'selected', false);
    }
  },
});
